"""
高级AI视频分类器

提供多级分类、特征提取和分类优化功能。
"""

import asyncio
import time
from typing import Dict, List, Any, Optional, Tuple
from datetime import datetime
import logging
import json

from src.core.di import Injectable, Inject
from src.modules.scanners.base import FileInfo, FileType, FileCategory
from src.services.gemini_service import GeminiService
from .base import AIClassifier, ClassificationResult


@Injectable(scope="singleton")
class AdvancedAIClassifier(AIClassifier):
    """
    高级AI视频分类器
    
    提供多级分类、特征提取和分类优化功能。
    """
    
    def __init__(self,
                 gemini_service: GeminiService = Inject(GeminiService),
                 config: Dict[str, Any] = Inject("config"),
                 logger: logging.Logger = Inject("logger")):
        self.gemini_service = gemini_service
        self.config = config
        self.logger = logger
        
        # 高级分类器配置
        self.ai_config = config.get("ai_classifier", {})
        self.confidence_threshold = self.ai_config.get("confidence_threshold", 0.7)
        self.max_frames = self.ai_config.get("max_frames_per_video", 5)
        self.enable_multi_level = self.ai_config.get("enable_multi_level", True)
        self.enable_feature_extraction = self.ai_config.get("enable_feature_extraction", True)
        
        # 分类层级定义
        self.classification_hierarchy = {
            "product_display": {
                "subcategories": ["main_image", "detail_shot", "feature_demo"],
                "features": ["product_focus", "static_display", "multiple_angles"]
            },
            "product_usage": {
                "subcategories": ["tutorial", "application_scene", "effect_comparison"],
                "features": ["hands_on_demo", "step_by_step", "before_after"]
            },
            "model_wearing": {
                "subcategories": ["front_view", "side_view", "back_view", "detail_view"],
                "features": ["human_model", "clothing_display", "fit_demonstration"]
            },
            "promotional": {
                "subcategories": ["advertisement", "social_media", "brand_promotion"],
                "features": ["marketing_style", "call_to_action", "brand_elements"]
            }
        }
    
    @property
    def name(self) -> str:
        return "advanced_ai_classifier"
    
    @property
    def version(self) -> str:
        return "2.0.0"
    
    @property
    def supported_file_types(self) -> List[str]:
        return ["video", "mp4", "avi", "mov", "mkv", "webm"]
    
    def is_available(self) -> bool:
        """检查分类器是否可用"""
        return self.gemini_service.is_available()
    
    async def classify(self, file_info: FileInfo, **kwargs) -> ClassificationResult:
        """高级分类视频文件"""
        start_time = time.time()
        
        # 检查文件类型
        if file_info.file_type != FileType.VIDEO:
            return ClassificationResult(
                success=False,
                error=f"不支持的文件类型: {file_info.file_type.value}",
                classifier_type=self.name,
                timestamp=datetime.now()
            )
        
        # 检查服务可用性
        if not self.is_available():
            return ClassificationResult(
                success=False,
                error="Gemini服务不可用",
                classifier_type=self.name,
                timestamp=datetime.now()
            )
        
        try:
            self.logger.info(f"使用高级AI分析视频: {file_info.name}")
            
            # 第一级：基础分类
            primary_result = await self._primary_classification(file_info, **kwargs)
            
            if not primary_result["success"]:
                return ClassificationResult(
                    success=False,
                    error=primary_result.get("error", "基础分类失败"),
                    classifier_type=self.name,
                    processing_time=time.time() - start_time,
                    timestamp=datetime.now()
                )
            
            # 第二级：细分分类（如果启用）
            secondary_result = None
            if self.enable_multi_level:
                secondary_result = await self._secondary_classification(
                    file_info, primary_result, **kwargs
                )
            
            # 特征提取（如果启用）
            features_result = None
            if self.enable_feature_extraction:
                features_result = await self._extract_detailed_features(
                    file_info, primary_result, **kwargs
                )
            
            # 合并结果
            final_result = self._merge_classification_results(
                primary_result, secondary_result, features_result
            )
            
            processing_time = time.time() - start_time
            
            # 转换为标准格式
            category_str = final_result.get("category", "unclassified")
            try:
                category = FileCategory(category_str)
            except ValueError:
                self.logger.warning(f"未知的分类类型: {category_str}")
                category = FileCategory.UNCLASSIFIED
            
            result = ClassificationResult(
                category=category,
                confidence=final_result.get("confidence", 0.0),
                reasoning=final_result.get("reasoning", ""),
                features=final_result.get("features", []),
                classifier_type=self.name,
                model_name=self.gemini_service.model_name,
                processing_time=processing_time,
                timestamp=datetime.now(),
                raw_response=final_result.get("raw_response", ""),
                metadata={
                    "primary_classification": primary_result,
                    "secondary_classification": secondary_result,
                    "feature_extraction": features_result,
                    "multi_level_enabled": self.enable_multi_level,
                    "feature_extraction_enabled": self.enable_feature_extraction,
                    "classification_hierarchy": self.classification_hierarchy.get(category_str, {})
                },
                success=True
            )
            
            self.logger.info(
                f"高级AI分类完成: {file_info.name} -> {category.value} "
                f"(置信度: {result.confidence:.2f}, 耗时: {processing_time:.2f}s)"
            )
            
            return result
            
        except Exception as e:
            processing_time = time.time() - start_time
            error_msg = f"高级AI分类失败: {e}"
            self.logger.error(error_msg)
            
            return ClassificationResult(
                success=False,
                error=error_msg,
                classifier_type=self.name,
                processing_time=processing_time,
                timestamp=datetime.now()
            )
    
    async def _primary_classification(self, file_info: FileInfo, **kwargs) -> Dict[str, Any]:
        """第一级：基础分类"""
        try:
            # 使用基础的Gemini分析
            result = await self.gemini_service.analyze_video_content(
                file_info.path,
                max_frames=kwargs.get("max_frames", self.max_frames)
            )
            
            if result.get("success"):
                self.logger.debug(f"基础分类完成: {file_info.name}")
            
            return result
            
        except Exception as e:
            self.logger.error(f"基础分类失败: {e}")
            return {"success": False, "error": str(e)}
    
    async def _secondary_classification(self, 
                                      file_info: FileInfo, 
                                      primary_result: Dict[str, Any], 
                                      **kwargs) -> Dict[str, Any]:
        """第二级：细分分类"""
        try:
            primary_category = primary_result.get("category", "unclassified")
            
            # 获取该分类的子分类
            hierarchy = self.classification_hierarchy.get(primary_category, {})
            subcategories = hierarchy.get("subcategories", [])
            
            if not subcategories:
                return {"success": True, "subcategory": None, "reasoning": "无子分类"}
            
            # 构建细分分类提示词
            prompt = self._build_secondary_classification_prompt(primary_category, subcategories)
            
            # 提取视频帧
            frames = await self.gemini_service.extract_video_frames(
                file_info.path, max_frames=3
            )
            
            # 发送请求
            response = await self.gemini_service._make_request(prompt, frames)
            
            if response:
                # 解析细分分类结果
                subcategory_result = self._parse_secondary_response(response, subcategories)
                subcategory_result["success"] = True
                return subcategory_result
            else:
                return {"success": False, "error": "细分分类响应为空"}
                
        except Exception as e:
            self.logger.error(f"细分分类失败: {e}")
            return {"success": False, "error": str(e)}
    
    async def _extract_detailed_features(self, 
                                       file_info: FileInfo, 
                                       primary_result: Dict[str, Any], 
                                       **kwargs) -> Dict[str, Any]:
        """提取详细特征"""
        try:
            primary_category = primary_result.get("category", "unclassified")
            
            # 构建特征提取提示词
            prompt = self._build_feature_extraction_prompt(primary_category)
            
            # 提取视频帧
            frames = await self.gemini_service.extract_video_frames(
                file_info.path, max_frames=5
            )
            
            # 发送请求
            response = await self.gemini_service._make_request(prompt, frames)
            
            if response:
                # 解析特征提取结果
                features_result = self._parse_features_response(response)
                features_result["success"] = True
                return features_result
            else:
                return {"success": False, "error": "特征提取响应为空"}
                
        except Exception as e:
            self.logger.error(f"特征提取失败: {e}")
            return {"success": False, "error": str(e)}
    
    def _build_secondary_classification_prompt(self, primary_category: str, subcategories: List[str]) -> str:
        """构建细分分类提示词"""
        subcategory_list = "\n".join([f"- {sub}" for sub in subcategories])
        
        return f"""
请对这个{primary_category}类型的视频进行更细致的分类。

可选的子分类：
{subcategory_list}

请以JSON格式回复：
{{
    "subcategory": "最合适的子分类",
    "confidence": 0.0-1.0的置信度,
    "reasoning": "选择理由"
}}

请仔细观察视频内容，选择最合适的子分类。
"""
    
    def _build_feature_extraction_prompt(self, primary_category: str) -> str:
        """构建特征提取提示词"""
        return f"""
请详细分析这个{primary_category}类型视频的特征。

请识别以下方面的特征：
1. 视觉特征：颜色、构图、光线、角度
2. 内容特征：主要对象、动作、场景
3. 技术特征：拍摄手法、剪辑风格、特效
4. 情感特征：氛围、情绪、风格

请以JSON格式回复：
{{
    "visual_features": ["视觉特征列表"],
    "content_features": ["内容特征列表"],
    "technical_features": ["技术特征列表"],
    "emotional_features": ["情感特征列表"],
    "overall_quality": 0.0-1.0的质量评分,
    "key_moments": ["关键时刻描述"]
}}
"""
    
    def _parse_secondary_response(self, response: str, subcategories: List[str]) -> Dict[str, Any]:
        """解析细分分类响应"""
        try:
            import json
            import re
            
            # 尝试提取JSON
            json_match = re.search(r'\{.*\}', response, re.DOTALL)
            if json_match:
                result = json.loads(json_match.group())
                
                subcategory = result.get("subcategory", "")
                confidence = float(result.get("confidence", 0.0))
                reasoning = result.get("reasoning", "")
                
                # 验证子分类是否有效
                if subcategory not in subcategories:
                    subcategory = subcategories[0] if subcategories else ""
                    confidence = 0.5
                
                return {
                    "subcategory": subcategory,
                    "confidence": confidence,
                    "reasoning": reasoning
                }
        except Exception as e:
            self.logger.warning(f"解析细分分类响应失败: {e}")
        
        # 回退到简单匹配
        response_lower = response.lower()
        for subcategory in subcategories:
            if subcategory.lower() in response_lower:
                return {
                    "subcategory": subcategory,
                    "confidence": 0.6,
                    "reasoning": "基于关键词匹配"
                }
        
        return {
            "subcategory": subcategories[0] if subcategories else "",
            "confidence": 0.3,
            "reasoning": "默认选择"
        }
    
    def _parse_features_response(self, response: str) -> Dict[str, Any]:
        """解析特征提取响应"""
        try:
            import json
            import re
            
            # 尝试提取JSON
            json_match = re.search(r'\{.*\}', response, re.DOTALL)
            if json_match:
                result = json.loads(json_match.group())
                
                return {
                    "visual_features": result.get("visual_features", []),
                    "content_features": result.get("content_features", []),
                    "technical_features": result.get("technical_features", []),
                    "emotional_features": result.get("emotional_features", []),
                    "overall_quality": float(result.get("overall_quality", 0.5)),
                    "key_moments": result.get("key_moments", [])
                }
        except Exception as e:
            self.logger.warning(f"解析特征提取响应失败: {e}")
        
        # 回退到简单特征提取
        return {
            "visual_features": ["基础视觉特征"],
            "content_features": ["基础内容特征"],
            "technical_features": ["基础技术特征"],
            "emotional_features": ["基础情感特征"],
            "overall_quality": 0.5,
            "key_moments": ["关键时刻"]
        }
    
    def _merge_classification_results(self, 
                                    primary: Dict[str, Any], 
                                    secondary: Optional[Dict[str, Any]], 
                                    features: Optional[Dict[str, Any]]) -> Dict[str, Any]:
        """合并分类结果"""
        # 基础结果来自主分类
        result = {
            "category": primary.get("category", "unclassified"),
            "confidence": primary.get("confidence", 0.0),
            "reasoning": primary.get("reasoning", ""),
            "features": primary.get("features", []),
            "raw_response": primary.get("raw_response", "")
        }
        
        # 添加细分分类信息
        if secondary and secondary.get("success"):
            subcategory = secondary.get("subcategory")
            if subcategory:
                result["subcategory"] = subcategory
                result["features"].append(f"子分类: {subcategory}")
                
                # 调整置信度（结合主分类和细分分类）
                secondary_confidence = secondary.get("confidence", 0.5)
                result["confidence"] = (result["confidence"] + secondary_confidence) / 2
                
                # 更新推理
                secondary_reasoning = secondary.get("reasoning", "")
                if secondary_reasoning:
                    result["reasoning"] += f" | 细分: {secondary_reasoning}"
        
        # 添加详细特征
        if features and features.get("success"):
            visual_features = features.get("visual_features", [])
            content_features = features.get("content_features", [])
            technical_features = features.get("technical_features", [])
            emotional_features = features.get("emotional_features", [])
            
            # 合并所有特征
            all_features = visual_features + content_features + technical_features + emotional_features
            result["features"].extend(all_features)
            
            # 添加质量评分
            quality = features.get("overall_quality", 0.5)
            result["quality_score"] = quality
            
            # 质量评分影响置信度
            quality_boost = (quality - 0.5) * 0.2  # 质量评分对置信度的影响
            result["confidence"] = min(1.0, result["confidence"] + quality_boost)
        
        return result
